/**
 *
 * @name:  子表格扩展
 * @author: yelog
 * @link: https://github.com/yelog/layui-soul-table
 * @license: MIT
 * @version: v1.6.1
 */
layui.define(['table', 'element', 'form', 'laytpl'], function (exports) {

    var $ = layui.jquery,
        table = layui.table,
        laytpl = layui.laytpl,
        tableChildren = {},
        HIDE = 'layui-hide',
        ELEM_HOVER = 'soul-table-hover';

    // 封装方法
    var mod = {
        /**
         * 渲染入口
         * @param myTable
         */
        render: function (myTable) {
            var _this = this,
                $table = $(myTable.elem),
                $tableBox = $table.next().children('.layui-table-box'),
                tableId = myTable.id,
                $tableHead = $tableBox.children('.layui-table-header').children('table'),
                $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'),
                $noFixedBody = $tableBox.children('.layui-table-body').children('table'),
                $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody),
                columns = _this.getCompleteCols(myTable.cols),
                childIndex = [],
                soulSort = typeof myTable.soulSort === 'undefined' || myTable.soulSort,
                i;

            // 修复hover样式
            _this.fixHoverStyle(myTable)
            // 获取子表配置信息
            for (i = 0; i < columns.length; i++) {
                if (columns[i].children && columns[i].children.length > 0) {
                    childIndex.push(i);
                }
            }
            if (typeof $table.attr('lay-filter') === 'undefined') {
                $table.attr('lay-filter', tableId);
            }
            // 绑定一下主表事件
            if ($table.parents('.childTr').length === 0) {
                // 行单击事件
                if (typeof myTable.rowEvent === 'function') {
                    table.on('row(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.rowEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
                // 行双击事件
                if (typeof myTable.rowDoubleEvent === 'function') {
                    table.on('rowDouble(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.rowDoubleEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
                // 绑定 checkbox 事件
                if (typeof myTable.checkboxEvent === 'function') {
                    table.on('checkbox(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.checkboxEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
                // 绑定 edit 事件
                if (typeof myTable.editEvent === 'function') {
                    table.on('edit(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.editEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
                // 绑定 tool 事件
                if (typeof myTable.toolEvent === 'function') {
                    table.on('tool(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.toolEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
                // 绑定 toolbar 事件
                if (typeof myTable.toolbarEvent === 'function') {
                    table.on('toolbar(' + $table.attr('lay-filter') + ')', function (obj) {
                        myTable.toolbarEvent(_this.commonMember.call(this, _this, myTable, obj));
                    })
                }
            }

            if (childIndex.length > 0) {
                for (i = 0; i < childIndex.length; i++) {
                    (function f() {
                        var child = columns[childIndex[i]]
                            , curIndex = childIndex[i]
                            , icon = child.icon || ['layui-icon layui-icon-right', 'layui-icon layui-icon-down'];

                        if (soulSort && !(myTable.url && myTable.page)) {
                            // 前台排序
                            table.on('sort(' + $table.attr('lay-filter') + ')', function () {
                                _this.render(myTable)
                            });
                        }

                        if (child.isChild && typeof child.isChild === 'function') {
                            $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').each(function () {
                                if (child.isChild(layui.table.cache[tableId][$(this).parents('tr:eq(0)').data('index')])) {
                                    if (child.field) {
                                        $(this).prepend('<i style="cursor: pointer" class="childTable ' + icon[0] + '"></i>');
                                    } else {
                                        $(this).html('<i style="cursor: pointer" class="childTable ' + icon[0] + '"></i>');
                                    }
                                }
                            })
                        } else {
                            if (child.field) {
                                $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').prepend('<i style="cursor: pointer" class="childTable ' + icon[0] + '"></i>');
                            } else {
                                $tableBody.find('tr').find('td[data-key$="' + child.key + '"]>div').html('<i style="cursor: pointer" class="childTable ' + icon[0] + '"></i>');
                            }
                        }

                        $tableBody.children('tbody').children('tr').each(function () {
                            $(this).children('td:eq(' + curIndex + ')').find('.childTable').on('click', function (e) {
                                layui.stope(e)
                                var rowIndex = $(this).parents('tr:eq(0)').data('index'),
                                    tableId = myTable.id,
                                    key = $(this).parents('td:eq(0)').data('key'),
                                    $this = $noFixedBody.children('tbody').children('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'),
                                    $fixedThis = $fixedBody.find('tr[data-index=' + rowIndex + ']').children('td[data-key="' + key + '"]').find('.childTable:eq(0)'),
                                    data = table.cache[tableId][rowIndex],
                                    children = child.children,
                                    isTpl = false,
                                    tplContent = '',
                                    tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
                                    obj = {
                                        data: data,
                                        tr: tr,
                                        del: function () {
                                            table.cache[tableId][rowIndex] = [];
                                            _this.destroyChildren(rowIndex, myTable, icon)
                                            tr.remove();
                                            table.resize(tableId);
                                        },
                                        update: function (fields) {
                                            fields = fields || {};
                                            layui.each(fields, function (key, value) {
                                                if (key in data) {
                                                    var templet, td = tr.children('td[data-field="' + key + '"]');
                                                    data[key] = value;
                                                    table.eachCols(tableId, function (i, item2) {
                                                        if (item2.field == key && item2.templet) {
                                                            templet = item2.templet;
                                                        }
                                                    });
                                                    td.children('.layui-table-cell').html(function () {
                                                        return templet ? function () {
                                                            return typeof templet === 'function'
                                                                ? templet(data)
                                                                : laytpl($(templet).html() || value).render(data)
                                                        }() : value;
                                                    }());
                                                    td.data('content', value);
                                                }
                                            });
                                        },
                                        close: function () {
                                            _this.destroyChildren(rowIndex, myTable, icon)
                                            table.resize(tableId);
                                        }

                                    };
                                if ($this.hasClass(icon[1])) {
                                    if (typeof child.childClose === 'function') {
                                        if (child.childClose(obj) === false) {
                                            return;
                                        }
                                    }
                                } else {
                                    // 展开事件
                                    if (typeof child.childOpen === 'function') {
                                        if (child.childOpen(obj) === false) {
                                            return;
                                        }
                                    }
                                }

                                if (typeof children === 'function') {
                                    children = children(data)
                                }
                                // 如果是 templet 自定义内容
                                if (typeof children === 'string') {
                                    isTpl = true
                                    tplContent = _this.parseTempData(child, child.field ? data[child.field] : null, data)
                                }
                                if (child.show === 2) { // 弹窗模式

                                    child.layerOption ? (typeof child.layerOption.title === 'function' ? (child.layerOption.title = child.layerOption.title(data)) : null) : null;
                                    layer.open($.extend({
                                        type: 1,
                                        title: '子表',
                                        maxmin: true,
                                        content: _this.getTables(this, data, child, myTable, children, isTpl, tplContent),
                                        area: '1000px',
                                        offset: '100px',
                                        cancel: function () {
                                            if (typeof child.childClose === 'function') {
                                                if (child.childClose(obj) === false) {
                                                    return;
                                                }
                                            }
                                        }
                                    }, child.layerOption || {}));

                                    if (!isTpl) {
                                        _this.renderTable(this, data, child, myTable, children, icon);
                                    }

                                } else { // 展开模式

                                    // 开启手风琴模式
                                    if (!$this.hasClass(icon[1]) && child.collapse) {
                                        $tableBody.children('tbody').children('tr').children('td').find('.childTable').each(function () {
                                            if ($(this).hasClass(icon[1])) {
                                                _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon)
                                            }
                                        })
                                    }

                                    // 多个入口时，关闭其他入口
                                    if (!$this.hasClass(icon[1])) {
                                        $this.parents('tr:eq(0)').children('td').find('.childTable').each(function () {
                                            if ($(this).hasClass(icon[1])) {
                                                $(this).removeClass(icon[1]).addClass(icon[0])
                                                _this.destroyChildren($(this).parents('tr:eq(0)').data('index'), myTable, icon)
                                            }
                                        })
                                    }

                                    if ($this.hasClass(icon[1])) {
                                        $this.removeClass(icon[1]).addClass(icon[0])
                                        $fixedThis.removeClass(icon[1]).addClass(icon[0])
                                    } else {
                                        $this.removeClass(icon[0]).addClass(icon[1])
                                        $fixedThis.removeClass(icon[0]).addClass(icon[1])
                                    }
                                    var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan");

                                    if ($this.hasClass(icon[1])) {
                                        var newTr = [];
                                        newTr.push('<tr data-tpl="' + isTpl + '" class="noHover childTr"><td colspan="' + $tableHead.find('th:visible').length + '"  style="cursor: inherit; padding: 0;">');
                                        newTr.push(_this.getTables(this, data, child, myTable, children, isTpl, tplContent));
                                        newTr.push('</td></tr>');

                                        if (rowspanIndex) {
                                            var index = parseInt($this.parents('tr:eq(0)').data("index")) + parseInt(rowspanIndex) - 1;
                                            $this.parents('table:eq(0)').children().children("[data-index='" + index + "']").after(newTr.join(''));
                                        } else {
                                            $this.parents('tr:eq(0)').after(newTr.join(''));
                                        }
                                        layui.element.init('tab')
                                        if (!isTpl) {
                                            _this.renderTable(this, data, child, myTable, children, icon);
                                            // 阻止事件冒泡
                                            $this.parents('tr:eq(0)').next().children('td').children('.layui-tab').children('.layui-tab-content').on('click', function (e) {
                                                // 不阻止 tab 切换点击事件
                                                if (!$(e.target.parentElement).hasClass('layui-tab-title')) {
                                                    e.stopPropagation()
                                                }
                                            }).off('dblclick').on('dblclick', function (e) {
                                                e.stopPropagation()
                                            }).on('mouseenter', 'td', function (e) {
                                                e.stopPropagation()
                                            }).on('change', function (e) {
                                                layui.stope(e)
                                            })
                                        }
                                        if ($fixedBody.length > 0) {
                                            var $tr = $this.parents('tr:eq(0)').next(),
                                                height = $tr.children('td').height(),
                                                $patchDiv = '<div class="soul-table-child-patch" style="height: ' + height + 'px"></div>';
                                            $tr.children('td').children('.soul-table-child-wrapper').css({
                                                position: 'absolute',
                                                top: 0,
                                                width: '100%',
                                                background: 'white',
                                                'z-index': 200
                                            })
                                            $tr.children('td').append($patchDiv);
                                            $fixedBody.find('tr[data-index="' + rowIndex + '"]').each(function () {
                                                $(this).after('<tr><td style="padding: 0;" colspan="' + $(this).children('[data-key]').length + '">' + $patchDiv + '</td></tr>')
                                            })
                                            table.resize(tableId)
                                        }
                                        if (child.show === 3) {
                                            $this.parents('tr:eq(0)').next().find('.layui-table-view').css({ margin: 0, 'border-width': 0 });
                                            $this.parents('tr:eq(0)').next().find('.layui-table-header').css('display', 'none');
                                        }

                                    } else {
                                        _this.destroyChildren(rowIndex, myTable, icon);
                                        table.resize(tableId)
                                    }

                                }
                            })

                        })

                        if (child.spread && child.show !== 2) {
                            $tableBody.children('tbody').children('tr').children('td').find('.childTable').trigger('click');
                        }
                    })()

                }
            }
        },
        /**
         * 生成子表内容
         * @param _this
         * @param data
         * @param child
         * @param myTable
         * @param children 子表配置
         * @param isTpl 是否是自定义模版
         * @param tplContent 自定义模版内容
         * @returns {string}
         */
        getTables: function (_this, data, child, myTable, children, isTpl, tplContent) {
            var tables = [],
                $table = $(myTable.elem),
                $tableBox = $table.next().children('.layui-table-box'),
                tableId = myTable.id,
                rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index'),
                $tableHead = $tableBox.children('.layui-table-header').children('table'),
                $tableMain = $table.next().children('.layui-table-box').children('.layui-table-body'),
                $tableBody = $tableMain.children('table'),
                scrollWidth = 0,
                i;
            if (isTpl) {
                tables.push('<div class="soul-table-child-wrapper" style="margin: 0;border: 0;box-shadow: none;');
            } else {
                tables.push('<div class="layui-tab layui-tab-card soul-table-child-wrapper" lay-filter="table-child-tab-' + rowTableId + '" style="margin: 0;border: 0;box-shadow: none;');
            }
            if (child.show === 2) {
                tables.push('max-width: ' + ($tableBody.width() - 2) + 'px">')
            } else if (child.show === 3) {
                //不限制宽度
                tables.push('">')
            } else {
                if (child.childWidth === 'full') {
                    //不限制宽度
                    tables.push('">')
                } else {
                    // 如果有滚动条
                    if ($tableMain.prop('scrollHeight') + (children.length > 0 ? children[0].height : 0) > $tableMain.height()) {
                        scrollWidth = this.getScrollWidth();
                    }
                    var maxWidth = $tableMain.width() - 1 - scrollWidth;
                    tables.push('max-width: ' + (maxWidth > $tableHead.width() ? $tableHead.width() : maxWidth) + 'px">')
                }
            }
            if (isTpl) {
                tables.push(tplContent)
            } else {
                if (child.show !== 3 && (typeof child.childTitle === 'undefined' || child.childTitle)) {
                    tables.push('<ul class="layui-tab-title">')
                    for (i = 0; i < children.length; i++) {
                        tables.push('<li class="' + (i === 0 ? 'layui-this' : '') + '">' + (typeof children[i].title === 'function' ? children[i].title(data) : children[i].title) + '</li>');
                    }
                    tables.push('</ul>')
                }
                if (child.show === 3) {
                    tables.push('<div class="layui-tab-content" style="padding: 0">');
                } else {
                    tables.push('<div class="layui-tab-content" style="padding: 0 10px">');
                }
                for (i = 0; i < children.length; i++) {
                    var childTableId = rowTableId + i;
                    tables.push('<div class="layui-tab-item layui-show"><form action="" class="layui-form" ><table id="' + childTableId + '" lay-filter="' + childTableId + '"></table></form></div>');
                }
                tables.push('</div>');
            }
            tables.push('</div>');
            return tables.join('')
        },
        /**
         * 渲染子表
         * @param _this
         * @param data 父表当前行数据
         * @param child 子表列
         * @param myTable 父表配置
         * @param children 子表配置
         * @param icon 自定义图标
         */
        renderTable: function (_this, data, child, myTable, children, icon) {
            var tables = []
                , _that = this
                , tableId = myTable.id
                , rowTableId = tableId + $(_this).parents('tr:eq(0)').data('index');

            if (child.lazy) {
                tables.push(renderChildTable(_that, _this, data, child, myTable, 0, children, icon));
            } else {
                for (var i = 0; i < children.length; i++) {
                    tables.push(renderChildTable(_that, _this, data, child, myTable, i, children, icon));
                }
            }
            tableChildren[rowTableId] = tables;


            layui.element.on('tab(table-child-tab-' + rowTableId + ')', function (tabData) {
                if (child.lazy) {
                    var isRender = false; // 是否已经渲染
                    for (i = 0; i < tableChildren[rowTableId].length; i++) {
                        if (tableChildren[rowTableId][i].config.id === (rowTableId + tabData.index)) {
                            isRender = true;
                            break;
                        }
                    }
                    if (!isRender) {
                        tableChildren[rowTableId].push(renderChildTable(_that, _this, data, child, myTable, tabData.index, children))
                    }
                }

                var rowIndex = $(_this).parents('tr:eq(0)').data('index'),
                    height = $(tabData.elem).height();

                $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
                $(_this).parents('.layui-table-box:eq(0)').children('.layui-table-fixed').children('.layui-table-body').children('table').children('tbody').children('tr[data-index=' + rowIndex + ']').next().children().children('.soul-table-child-patch').css('height', height)
                table.resize(tableId)

            });


            function renderChildTable(_that, _this, data, child, myTable, i, children, icon) {
                var param = _that.deepClone(children[i]), thisTableChild,
                    tableId = myTable.id,
                    rowIndex = $(_this).parents('tr:eq(0)').data('index'),
                    childTableId = tableId + rowIndex + i,
                    $table = $(myTable.elem),
                    $tableBox = $table.next().children('.layui-table-box'),
                    $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')),
                    tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
                    row = table.cache[tableId][rowIndex],
                    // 父表当前行对象
                    pobj = {
                        data: row,
                        tr: tr,
                        del: function () {
                            table.cache[tableId][rowIndex] = [];
                            _that.destroyChildren(rowIndex, myTable, icon)
                            tr.remove();
                            table.resize(tableId);
                        },
                        update: function (fields) {
                            fields = fields || {};
                            layui.each(fields, function (key, value) {
                                if (key in row) {
                                    var templet, td = tr.children('td[data-field="' + key + '"]');
                                    row[key] = value;
                                    table.eachCols(tableId, function (i, item2) {
                                        if (item2.field == key && item2.templet) {
                                            templet = item2.templet;
                                        }
                                    });
                                    td.children('.layui-table-cell').html(function () {
                                        return templet ? function () {
                                            return typeof templet === 'function'
                                                ? templet(row)
                                                : laytpl($(templet).html() || value).render(row)
                                        }() : value;
                                    }());
                                    td.data('content', value);
                                }
                            });
                        },
                        close: function () {
                            _that.destroyChildren(rowIndex, myTable, icon)
                            table.resize(tableId);
                        }

                    };
                param.id = childTableId;
                param.elem = '#' + childTableId;
                typeof param.where === 'function' && (param.where = param.where(data));
                typeof param.data === 'function' && (param.data = param.data(data));
                typeof param.url === 'function' && (param.url = param.url(data));
                thisTableChild = table.render(param);
                if (!child.lazy && i !== 0) {
                    $('#' + childTableId).parents('.layui-tab-item:eq(0)').removeClass('layui-show'); //解决隐藏时计算表格高度有问题
                }
                // 绑定 checkbox 事件
                if (typeof param.checkboxEvent === 'function') {
                    table.on('checkbox(' + childTableId + ')', function (obj) {
                        param.checkboxEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                // 绑定 edit 事件
                if (typeof param.editEvent === 'function') {
                    table.on('edit(' + childTableId + ')', function (obj) {
                        param.editEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                // 绑定 tool 事件
                if (typeof param.toolEvent === 'function') {
                    table.on('tool(' + childTableId + ')', function (obj) {
                        param.toolEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                // 绑定 toolbar 事件
                if (typeof param.toolbarEvent === 'function') {
                    table.on('toolbar(' + childTableId + ')', function (obj) {
                        param.toolbarEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                // 绑定单击行事件
                if (typeof param.rowEvent === 'function') {
                    table.on('row(' + childTableId + ')', function (obj) {
                        param.rowEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                // 绑定双击行事件
                if (typeof param.rowDoubleEvent === 'function') {
                    table.on('rowDouble(' + childTableId + ')', function (obj) {
                        param.rowDoubleEvent(_that.commonMember.call(this, _that, param, obj), pobj)
                    })
                }
                return thisTableChild;
            }
        },
        destroyChildren: function (rowIndex, myTable, icon) {
            var tableId = myTable.id,
                $table = $(myTable.elem),
                $tableBox = $table.next().children('.layui-table-box'),
                $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table'),
                $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody),
                $tr = $tableBody.children('tbody').children('tr[data-index="' + rowIndex + '"]'),
                isTpl = $tr.next().data('tpl');

            $tr.find('.childTable').removeClass(icon[1]).addClass(icon[0]);

            // 暂时不处理 rowspan 情况
            // var rowspanIndex = $this.parents('td:eq(0)').attr("rowspan");
            // if(rowspanIndex){
            //     var index=$this.parents('tr:eq(0)').index()+parseInt(rowspanIndex);
            //     $this.parents('table:eq(0)').children().children('tr:eq('+index+')').remove()
            // }else{
            //     $this.parents('tr:eq(0)').next().remove();
            // }
            $tr.next().remove()
            if (isTpl === 'false') {
                var tables = tableChildren[tableId + rowIndex];
                if (layui.tableFilter) { //如果使用了筛选功能，同时清理筛选渲染的数据
                    layui.tableFilter.destroy(tables);
                }
                if (layui.soulTable) { // 清除记忆
                    for (var i = 0; i < tableChildren[tableId + rowIndex].length; i++) {
                        layui.soulTable.clearOriginCols(tableChildren[tableId + rowIndex][i].config.id)
                    }
                }
            }
            delete tableChildren[tableId + rowIndex]

        },
        cloneJSON: function (obj) {
            var JSON_SERIALIZE_FIX = {
                PREFIX: "[[JSON_FUN_PREFIX_",
                SUFFIX: "_JSON_FUN_SUFFIX]]"
            };
            var sobj = JSON.stringify(obj, function (key, value) {
                if (typeof value === 'function') {
                    return JSON_SERIALIZE_FIX.PREFIX + value.toString() + JSON_SERIALIZE_FIX.SUFFIX;
                }
                return value;
            });
            return JSON.parse(sobj, function (key, value) {
                if (typeof value === 'string' &&
                    value.indexOf(JSON_SERIALIZE_FIX.SUFFIX) > 0 && value.indexOf(JSON_SERIALIZE_FIX.PREFIX) === 0) {
                    return eval("(" + value.replace(JSON_SERIALIZE_FIX.PREFIX, "").replace(JSON_SERIALIZE_FIX.SUFFIX, "") + ")");
                }
                return value;
            }) || {};
        },
        fixHoverStyle: function (myTable) {
            var $table = $(myTable.elem)
                , $tableBody = $table.next().children('.layui-table-box').children('.layui-table-body').children('table')
                ,
                $tableFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed').children('.layui-table-body').children('table')
                , style = $table.next().find('style')[0],
                sheet = style.sheet || style.styleSheet || {};
            // 屏蔽掉layui原生 hover 样式
            this.addCSSRule(sheet, '.layui-table-hover', 'background-color: inherit');
            this.addCSSRule(sheet, '.layui-table-hover.soul-table-hover', 'background-color: #F2F2F2');
            $.merge($tableFixed.children('tbody').children('tr'), $tableBody.children('tbody').children('tr'))
                .on('mouseenter', function () {
                    var othis = $(this)
                        , index = $(this).data('index');
                    if (othis.data('off')) return;
                    $tableFixed.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
                    $tableBody.children('tbody').children('tr[data-index=' + index + ']').addClass(ELEM_HOVER);
                }).on('mouseleave', function () {
                    var othis = $(this)
                        , index = $(this).data('index');
                    if (othis.data('off')) return;
                    $tableFixed.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
                    $tableBody.children('tbody').children('tr[data-index=' + index + ']').removeClass(ELEM_HOVER);
                })
        },
        addCSSRule: function (sheet, selector, rules, index) {
            if ('insertRule' in sheet) {
                sheet.insertRule(selector + '{' + rules + '}', index)
            } else if ('addRule' in sheet) {
                sheet.addRule(selector, rules, index)
            }
        },
        // 深度克隆-不丢失方法
        deepClone: function (obj) {
            var newObj = Array.isArray(obj) ? [] : {}
            if (obj && typeof obj === "object") {
                for (var key in obj) {
                    if (obj.hasOwnProperty(key)) {
                        newObj[key] = (obj && typeof obj[key] === 'object') ? this.deepClone(obj[key]) : obj[key];
                    }
                }
            }
            return newObj
        },
        getCompleteCols: function (origin) {
            var cols = this.deepClone(origin);
            var i, j, k, cloneCol;
            for (i = 0; i < cols.length; i++) {
                for (j = 0; j < cols[i].length; j++) {
                    if (!cols[i][j].exportHandled) {
                        if (cols[i][j].rowspan > 1) {
                            cloneCol = this.deepClone(cols[i][j])
                            cloneCol.exportHandled = true;
                            k = i + 1;
                            while (k < cols.length) {
                                cols[k].splice(j, 0, cloneCol)
                                k++
                            }
                        }
                        if (cols[i][j].colspan > 1) {
                            cloneCol = this.deepClone(cols[i][j])
                            cloneCol.exportHandled = true;
                            for (k = 1; k < cols[i][j].colspan; k++) {
                                cols[i].splice(j, 0, cloneCol)
                            }
                            j = j + parseInt(cols[i][j].colspan) - 1
                        }
                    }
                }
            }
            return cols[cols.length - 1];
        },
        getScrollWidth: function (elem) {
            var width = 0;
            if (elem) {
                width = elem.offsetWidth - elem.clientWidth;
            } else {
                elem = document.createElement('div');
                elem.style.width = '100px';
                elem.style.height = '100px';
                elem.style.overflowY = 'scroll';

                document.body.appendChild(elem);
                width = elem.offsetWidth - elem.clientWidth;
                document.body.removeChild(elem);
            }
            return width;
        },
        //解析自定义模板数据
        parseTempData: function (item3, content, tplData, text) { //表头数据、原始内容、表体数据、是否只返回文本
            var str = item3.children ? function () {
                return typeof item3.children === 'function'
                    ? item3.children(tplData)
                    : laytpl($(item3.children).html() || String(content)).render(tplData)
            }() : content;
            return text ? $('<div>' + str + '</div>').text() : str;
        },
        commonMember: function (_this, myTable, sets) {
            var othis = $(this)
                , tableId = myTable.id
                , $table = $(myTable.elem)
                , $tableBox = $table.next().children('.layui-table-box')
                , $fixedBody = $tableBox.children('.layui-table-fixed').children('.layui-table-body').children('table')
                , $tableBody = $.merge($tableBox.children('.layui-table-body').children('table'), $fixedBody)
                , index = othis[0].tagName === 'TR' ? $(this).data('index') : othis.parents('tr:eq(0)').data('index')
                , tr = $tableBody.children('tbody').children('tr[data-index="' + index + '"]')
                , data = table.cache[tableId] || [];


            data = data[index] || {};

            return $.extend(sets, {
                tr: tr //行元素
                , oldValue: othis.prev() ? othis.prev().text() : null
                , del: function () { //删除行数据
                    table.cache[tableId][index] = [];
                    tr.remove();
                    _this.scrollPatch(myTable);
                }
                , update: function (fields) { //修改行数据
                    fields = fields || {};
                    layui.each(fields, function (key, value) {
                        if (key in data) {
                            var templet, td = tr.children('td[data-field="' + key + '"]');
                            data[key] = value;
                            table.eachCols(tableId, function (i, item2) {
                                if (item2.field == key && item2.templet) {
                                    templet = item2.templet;
                                }
                            });
                            td.children('.layui-table-cell').html(_this.parseTempData({
                                templet: templet
                            }, value, data));
                            td.data('content', value);
                        }
                    });
                }
            });
        },
        scrollPatch: function (myTable) {
            var $table = $(myTable.elem),
                layHeader = $table.next().children('.layui-table-box').children('.layui-table-header'),
                layTotal = $table.next().children('.layui-table-total'),
                layMain = $table.next().children('.layui-table-box').children('.layui-table-main'),
                layFixed = $table.next().children('.layui-table-box').children('.layui-table-fixed'),
                layFixRight = $table.next().children('.layui-table-box').children('.layui-table-fixed-r'),
                layMainTable = layMain.children('table'),
                scollWidth = layMain.width() - layMain.prop('clientWidth'),
                scollHeight = layMain.height() - layMain.prop('clientHeight'),
                outWidth = layMainTable.outerWidth() - layMain.width() //表格内容器的超出宽度

                //添加补丁
                , addPatch = function (elem) {
                    if (scollWidth && scollHeight) {
                        elem = elem.eq(0);
                        if (!elem.find('.layui-table-patch')[0]) {
                            var patchElem = $('<th class="layui-table-patch"><div class="layui-table-cell"></div></th>'); //补丁元素
                            patchElem.find('div').css({
                                width: scollWidth
                            });
                            elem.find('tr').append(patchElem);
                        }
                    } else {
                        elem.find('.layui-table-patch').remove();
                    }
                }

            addPatch(layHeader);
            addPatch(layTotal);

            //固定列区域高度
            var mainHeight = layMain.height()
                , fixHeight = mainHeight - scollHeight;
            layFixed.find('.layui-table-body').css('height', layMainTable.height() >= fixHeight ? fixHeight : 'auto');

            //表格宽度小于容器宽度时，隐藏固定列
            layFixRight[outWidth > 0 ? 'removeClass' : 'addClass'](HIDE);

            //操作栏
            layFixRight.css('right', scollWidth - 1);
        }
    };

    // 输出
    exports('tableChild', mod);
});

